﻿using System.Collections.Specialized;
using System.Data;

namespace Loki.Data
{
    /// <summary>
    /// Interface for database adapters.
    /// </summary>
    public interface IDatabaseAdapter
    {
        /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
        string ConnectionString
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the current user.
        /// </summary>
        string CurrentUser { get; }

        /// <summary>
        /// Gets the datasource description.
        /// </summary>
        string DataSourceDescription { get; }

        /// <summary>
        /// Gets a value indicating whether this <see cref="IDatabaseAdapter" /> is initialized.
        /// </summary>
        /// <value>Is <c>true</c> if initialized; otherwise, /c>.</value>
        bool Initialized { get; }

        /// <summary>
        /// Bulks insert in the database.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns>The number of updated lines.</returns>
        int BulkInsert(DataTable table);

        /// <summary>
        /// Creates the command.
        /// </summary>
        /// <param name="name">Name of the command.</param>
        /// <returns>The command.</returns>
        IDatabaseCommand CreateCommand(string name);

        /// <summary>
        /// Creates the command.
        /// </summary>
        /// <param name="name">Name of the command.</param>
        /// <param name="type">Type of the command.</param>
        /// <returns>The command.</returns>
        IDatabaseCommand CreateCommand(string name, CommandType type);

        /// <summary>
        /// Initialize the database (if available).
        /// </summary>
        /// <param name="configParams">The config parameters.</param>
        void Initialize(NameValueCollection configParams);

        #region Query execution

        /// <summary>
        /// Executes the batch.
        /// </summary>
        /// <param name="batchCommands">The batch commands.</param>
        void ExecuteBatch(string batchCommands);

        /// <summary>
        /// Executes command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="transaction">The transaction.</param>
        void ExecuteNonQuery(IDatabaseCommand command, IDbTransaction transaction);

        /// <summary>
        /// Executes the query.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="transaction">The transaction.</param>
        /// <returns>The recordset.</returns>
        IDataReader ExecuteQuery(IDatabaseCommand command, IDbTransaction transaction);

        /// <summary>
        /// Executes the query and return an unique value.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="transaction">The transaction.</param>
        /// <returns>The query result.</returns>
        object ExecuteScalar(IDatabaseCommand command, IDbTransaction transaction);

        #endregion Query execution

        #region Transaction

        /// <summary>
        /// Commits the transaction.
        /// </summary>
        /// <param name="tran">The transaction.</param>
        /// <returns>True if the transaction commits successfully.</returns>
        bool CommitTransaction(IDbTransaction tran);

        /// <summary>
        /// Opens a new transaction on the database.
        /// </summary>
        /// <returns>The transaction.</returns>
        IDbTransaction OpenTransaction();

        /// <summary>
        /// Opens a new transaction on the database with the specified isolation level.
        /// </summary>
        /// <param name="level">The isolation level.</param>
        /// <returns>The transaction.</returns>
        IDbTransaction OpenTransaction(IsolationLevel level);

        /// <summary>
        /// Rollbacks the transaction.
        /// </summary>
        /// <param name="tran">The transaction.</param>
        /// <returns>True if the transaction rollbacks successfully.</returns>
        bool RollbackTransaction(IDbTransaction tran);

        #endregion Transaction
    }
}